﻿using Inovout.Data.Domain;
using Inovout.Descriptor;
using Inovout.Data.Service;
using Inovout.Serializer;
using Inovout.Web.Mvc;
using KuaJing.Tasks.Domain;
using SumPower.MailAccount.Web.XMail263Service;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace KuaJing.Tasks.WebPages.Controllers
{
    public class TaskController : RepositoryController<Task>
    {
        internal static readonly XmapiImplService x263Service = new XmapiImplService();
        internal const string key = "uieHDj93Wx";
        internal const string domain = "samples.cn";
        internal const string account = "samples.cn";
        public override ActionResult Index(QueryCriteria queryCriteria)
        {
            return View(QueryCriteriaBuilder.FilterFor(t => t.Name, FilterOperation.Like)
                .FilterFor(t => t.Assignee, FilterOperation.Like)
                .FilterFor(t => t.Participants, FilterOperation.Like)
               .FilterFor(t => t.ExpectedEndDate, FilterOperation.GtEq)
               .FilterFor(t => t.ExpectedEndDate, FilterOperation.LeEq)
               .FilterFor(t => t.Status, FilterOperation.Eq)
               .OrderFor(t => t.ExpectedEndDate)
               .Merge(queryCriteria));
        }
        public override ActionResult New()
        {
            return View("Edit", new Task { ExpectedStartDate = DateTime.Now, ExpectedEndDate = DateTime.Now.AddDays(5) });
        }

        public ActionResult SendMail(QueryCriteria queryCriteria)
        {
            var result = this.ModelService.Query(queryCriteria).GroupBy(t => t.Assignee).AsEnumerable();
            return View("Mail", result);
        }
        [HttpPost]
        public ActionResult SendMail(string cc = "")
        {
            QueryCriteria queryCriteria = new QueryCriteria(typeof(Task));
            if (Request.QueryString.AllKeys.Contains(QueryCriteriaHelper.RequestQueryFilterKey))
            {
                queryCriteria.Filters = QueryCriteriaHelper.ParseFilter(Request.QueryString[QueryCriteriaHelper.RequestQueryFilterKey]).ToList();
            }
            var result = this.ModelService.Query(queryCriteria).GroupBy(t => t.Assignee).AsEnumerable();
            var smtpClient = new SmtpClient();
            foreach (var taskGroup in result)
            {
                MailMessage message = new MailMessage()
                {
                    IsBodyHtml = true,
                    Subject = "关注的任务清单"
                };
                foreach (var to in Split(taskGroup.Key))
                {
                    message.To.Add(to);
                }
                foreach (var c in Split(cc))
                {
                    message.To.Add(c);
                }
                using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
                {
                    //< link type = "text/css" rel = "stylesheet" href = "//apps.bdimg.com/libs/bootstrap/3.2.0/css/bootstrap.min.css" />
                    //< link type = "text/css" rel = "stylesheet" href = "/Styles/iui/1.0.0/cSun.css" />
                    //< link type = "text/css" rel = "stylesheet" href = "/Styles/iui/1.0.0/Themes/Default/tWidget.css" />
                    //foreach (var css in new string[] { "/Styles/iui/1.0.0/cSun.css", "/Styles/iui/1.0.0/Themes/Default/tWidget.css" })
                    //{
                    //    writer.WriteLine(System.IO.File.ReadAllText(Server.MapPath(css)));
                    //}
                    writer.WriteLine(taskGroup.Key + "，你好！");
                    writer.WriteLine("    你有如下任务需要关注！");
                    ViewData.Model = taskGroup;
                    ViewEngineResult viewEngineResult = ViewEngines.Engines.FindPartialView(ControllerContext, "Table");
                    viewEngineResult.View.Render(new ViewContext(ControllerContext, viewEngineResult.View, ViewData, TempData, writer), writer);
                    message.Body = writer.ToString();
                    ViewData.Model = null;

                }
                smtpClient.Send(message);

            }
            return RedirectToReturnUrl();
        }

        public ActionResult Report(QueryCriteria queryCriteria)
        {
            var mergeQueryCriteria = new QueryCriteriaBuilder<Task>()
                  .FilterFor(t => t.ExpectedEndDate, FilterOperation.GtEq, DateTime.Now.AddDays(-7))
                  .FilterFor(t => t.ExpectedEndDate, FilterOperation.LeEq, DateTime.Now)
                  .Merge(queryCriteria).QueryCriteria;

            var taskService = GetService<IRepositoryForControllerService<Task>>();
            var tasks = taskService.StatelessQuery(mergeQueryCriteria).ToArray();
            ViewData.SetQueryCriteria(mergeQueryCriteria, tasks);

            var statusReportData = tasks.GroupBy(t => t.Status,
                  (key, t) =>
                  {
                      string alias = key.ToAlias();
                      return new object[] { alias, t.Count() };
                  });
            ViewBag.StatusReportData = JsonNetSerializer.Serialize(statusReportData, statusReportData.GetType());

            var executingTasks = tasks.Where(t => t.Status == TaskStatus.Executing);
            ViewBag.ExecutingTasks = executingTasks.OrderBy(t => t.Assignee);
            var assigneeReportData = executingTasks.GroupBy(t => t.Assignee,
               (key, t) => new object[] { key, t.Count() });
            ViewBag.AssigneeReportData = JsonNetSerializer.Serialize(assigneeReportData, assigneeReportData.GetType());

            return View(tasks);
        }

        public ActionResult SendMail(QueryCriteria queryCriteria, string cc = "")
        {
            var taskService = GetService<IRepositoryForControllerService<Task>>();
            var tasks = taskService.StatelessQuery(queryCriteria).Where(t => t.Status == TaskStatus.Executing);
            var smtpClient = new SmtpClient();

            MailMessage message = new MailMessage()
            {
                IsBodyHtml = true,
                Subject = "未完成的任务清单"
            };
            foreach (var to in TaskController.Split("马风奎，石滨，国莅丽，龚必锋，王小康，周高航，张慧荣，岑爱芬，廖燕，周原，伍会，朱守强，滕小芳，华永"))
            {
                message.To.Add(to);
            }

            using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
            {

                writer.WriteLine("各位，你们好！");
                writer.WriteLine("    未完成的任务清单如下！");
                ViewData.Model = tasks;
                ViewEngineResult viewEngineResult = ViewEngines.Engines.FindPartialView(ControllerContext, "~/Views/Task/Table.cshtml");
                viewEngineResult.View.Render(new ViewContext(ControllerContext, viewEngineResult.View, ViewData, TempData, writer), writer);
                message.Body = writer.ToString();
                ViewData.Model = null;

            }
            smtpClient.Send(message);

            return RedirectToReturnUrl();
        }


        internal static string[] Split(string content)
        {
            var result = content.Trim().Replace('；', ',').Replace('，', ',').Replace(' ', ',').Replace(';', ',').Split(',');
            return GetMail(result);
        }

        internal static string[] GetMail(params string[] names)
        {
            names = names.Where(n => !string.IsNullOrEmpty(n)).ToArray();
            var users = GetUsers();
            string[] emails = new string[names.Length];
            for (int i = 0; i < emails.Length; i++)
            {
                if (users.ContainsKey(names[i]))
                {
                    emails[i] = users[names[i]];
                }
            }
            return emails.Where(n => !string.IsNullOrEmpty(n)).ToArray();

        }
        internal static Dictionary<string, string> GetUsers()
        {
            Dictionary<string, string> userDictionary = new Dictionary<string, string>();
            string sign = Md5Sign(domain + account + key);
            var xmlString = x263Service.getDomainUserlist_New(domain, account, sign);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(xmlString);
            foreach (XmlNode userNode in xmlDocument.DocumentElement.ChildNodes)
            {
                userDictionary[userNode["name"].InnerText] = userNode["userid"].InnerText;

            }
            return userDictionary;
            //XElement usersXml = XElement.Parse(xmlString, LoadOptions.PreserveWhitespace);
            //var ab = usersXml.XPathSelectElement("userlist");
            //var abcd= usersXml.Descendants().Select(u => u.Descendants("name"));
            //return usersXml.Descendants().Select(u => u.Descendants("name").First().Value);
        }
        internal static string Md5SignArg(string userid = "")
        {
            return Md5Sign(userid + domain + account + key);

        }

        internal static string Md5Sign(string value)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] buffer = Encoding.Default.GetBytes(value);
            string result = BitConverter.ToString(md5.ComputeHash(buffer));
            return result.Replace("-", "").ToLower();
        }
        internal static IEnumerable<XElement> GetDepartments()
        {
            string xml = x263Service.getDepartment("huay", domain, account, Md5SignArg("huay"));
            return XDocument.Parse(xml).Descendants("department");
        }
        internal static IEnumerable<XElement> GetEmployees()
        {
            string xml = x263Service.getDomainUserlist_New(domain, account, Md5SignArg());
            return XDocument.Parse(xml).Descendants("user");

        }
    }
}